﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using ServiceOfSansar.Models;

namespace ServiceOfSansar
{
    [ErrorHandler]
    [ServiceContract(Namespace = "Sansar")]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    //Business Logic
    public class Transfer
    {
        #region Database
        private SansarEntities db;
        TelnetConnection tc;
        public Transfer()
        {
            db = new SansarEntities();
        }
        ~Transfer()
        {
            db.Dispose();
        }
        #endregion

        #region Авлага үүсгэх
        /*
         * АВЛАГА ҮҮСГЭХ
         * Дараах тохиолдолд авалага үүснэ
         *  1. Бүтээгдэхүүн солигдох үед
         *     Энэ үед хуучин бүтээгдэхүүнээр өртгийг нь бодоод авлагыг нэмж авлага бодсон огноог шинэчлэнэ
         *  2. Салбар дээр ирж төлбөр төлсөн гүйлгээ хийсэн тохиолдолд
         *  3. Хугацаа болж банкинд нэхэмжлэх явуулах тохиолдолд         
         *     Авлага нь
         *      Дараа төлбөрт үйлчилгээ
         *          - Сар болгоны N хоногт үүсгэнэ
         *      Урьдчилсан төлбөрт үйлчилгээд тус тус үүнэ
         *          - Энэ үйлчилгээнд үүсэхдээ тухайн үйлчилгээний хугацаа дуусахаас N хоногийн өмнө авлага үүсгэж банкинд мэдэгдэнэ
         *          
         * Авлага бодох бүрд гүйлгээ хийгднэ. Төлөх хийгдэх болгон тухайн авлагыг хааж явья
         */

        //Бүтээгдэхүүн солигдох үед үүсэх авлага
        [OperationContract]
        public Result ChangeProduct(int ContractId, int NewProdId)
        {

            return new Result(0, "Бүтээгдэхүүн амжилттай солигдлоо");
        }
        //Салбар дээр ирж төлбөр төлөгдсөн гүйлгээ хийгдэх
        public Result PaidBill()
        {
            return new Result(0, "Авлагын огноог өөчиллөө");
        }

        //Банкинд зориулж авлага үүсгэх
        public List<BankBill> BankBillList()
        {
            return null;
        }
        #endregion


        #region
        [OperationContract] //Гүйлгээ хийх
        public Result Reject(long trans_no, Transaction rej_trans)
        {
            try
            {
                var trans = db.Transactions.FirstOrDefault(w => w.TransNo == trans_no);
                trans.Status = 0;

                db.Transactions.AddObject(rej_trans);
                db.SaveChanges();

                return new Result() { Code = 0, Message = "Буцаалтын гүйлгээ амжилттай хийгдлээ" };
            }
            catch (Exception ex)
            {
                return new Result(1, "Гүйлгээ хийхэд алдаа:" + ex.Message);
            }
        }


        [OperationContract] //Гүйлгээ хийх
        public Result DoTransaction(Transaction[] trans,SendTransfer[] edit_trans, SendContract contract)
        {
            try
            {
                var con = db.Contracts.FirstOrDefault(w => w.ContractNo == contract.ContractNo);
                if (con == null)
                    return new Result(201, "Гэрээний дугаар буруу");
                if (contract.Balance != null)
                    con.Balance = contract.Balance ?? 0;

                if (contract.CurrProdCode != null)
                    con.CurrProdCode = contract.CurrProdCode ?? 0;

                if (contract.EndDate != null)
                    con.EndDate = contract.EndDate;

                if (contract.StartDate != null)
                    con.StartDate = contract.StartDate;

                if (contract.BalanceDate != null)
                    con.BalDate = contract.BalanceDate;
                if (contract.PauseDate != null)
                    con.PauseDate = contract.PauseDate;
                if (contract.Status != null)
                    con.Status = contract.Status??0;
                db.SaveChanges();
                var jr = db.Journals.Take(1).FirstOrDefault();
                jr.JrNo = jr.JrNo + 1;
                bool isAddUtm = false;
                bool isPause = false;
                bool isRun = false;
                int prod = 0;
                DateTime sDate=DateTime.Now;
                DateTime eDate = DateTime.Now;
                for (int i = 0; i < trans.Count(); i++)
                {
                    if (trans[i].TxnType == 1200 || trans[i].TxnType == 1201) isAddUtm = true;
                    if (trans[i].TxnType == 1000) isPause = true;
                    if (trans[i].TxnType == 1001) isRun = true;
                    trans[i].JrNo = jr.JrNo;
                    trans[i].PostDate = DateTime.Now;
                    db.Transactions.AddObject(trans[i]);
                }
                bool isRunToday = false;
                foreach (var edit in edit_trans)
                {
                    var i=db.Transactions.FirstOrDefault(d => d.TransNo == edit.TransNo);
                    if (i == null)
                        return new Result(201, "Гүйлгээний дугаар буруу. "+edit.TransNo);
                    if (edit.Status != null)
                    {
                        i.Status = edit.Status ?? 0;
                    }

                    if (edit.StartDate != null)
                    {
                        i.StartDate = edit.StartDate;
                        if ((edit.StartDate?? DateTime.Now.AddDays(1)).ToString("yyyyMMdd")==DateTime.Now.ToString("yyyyMMdd"))
                        {
                            isRunToday = true;
                            sDate = edit.StartDate?? DateTime.Now;
                            eDate= edit.EndDate?? DateTime.Now;
                            prod = i.ProdCode??0;
                        }
                    }

                    if (edit.EndDate != null)
                        i.EndDate = edit.EndDate; 
                }

                db.SaveChanges();
                // UTM deer guilgee oruulj bui heseg
                Result res = new Result() { Code = 0 };
                try
                {
                    if (isAddUtm && DateTime.Now.ToString("yyyyMMdd").Equals((contract.StartDate ?? DateTime.Now).ToString("yyyyMMdd")))
                    {
                        res = (new UtmInterface()).addServce(
                            con.UserName,
                            con.UserName,
                            con.Password,
                            con.CurrProdCode,
                            con.StartDate,
                            con.EndDate);
                    }
                    else if (isRun && isRunToday)
                    {
                        res = (new UtmInterface()).addServce(
                                con.UserName,
                                con.UserName,
                                con.Password,
                                prod,
                                sDate,
                                eDate);
                    }
                    else if (isPause)
                    {
                        res = (new UtmInterface()).DeleteAllService(con.UserName);
                    }
                }
                catch (Exception e)
                {
                    res.Code = 1;
                    res.Message = e.Message;
                }
                if (res.Code != 0) 
                    return new Result() { Code = 0, Message = "Гүйлгээ амжилттай хийгдсэн боловч UTM дээр алдаа гарав! "+ res.Message, RetData = jr.JrNo };
                else
                {
                    string s = (isRun || isPause || isAddUtm) ? ", UTM амжилттай" : "";
                    return new Result() { Code = 0, Message = "Гүйлгээ амжилттай" + s, RetData = jr.JrNo };
                }
            }
            catch (Exception ex)
            {
                return new Result(1, "Гүйлгээ хийхэд алдаа:" + ex.Message);
            }
        }

        [OperationContract] //Edit
        public Result DeleteAllService(long ContractNo)
        {
            var con = db.Contracts.FirstOrDefault(w => w.ContractNo == ContractNo);
            if (con == null)
                return new Result(201, "Гэрээний дугаар буруу");
            Result retItem = (new UtmInterface()).DeleteAllService(con.UserName);
            return new Result { Code = retItem.Code, Message = retItem.Message, RetData = 0 };
        }
        [OperationContract] //Edit
        public Result addService(long ContractNo, int prodcode, DateTime startdate, DateTime enddate)
        {
            var con = db.Contracts.FirstOrDefault(w => w.ContractNo == ContractNo);
            if (con == null)
                return new Result(201, "Гэрээний дугаар буруу");
            Result res = new Result() { Code = 0 };
            
            res = (new UtmInterface()).addServce(
                con.UserName,
                con.UserName,
                con.Password,
                prodcode,
                startdate,
                enddate);
            return res;
    }
    
        [OperationContract]
        public List<vw_Transaction> TransactionList(string query)
        {
            return db.vw_Transaction
                    .Where(query).OrderByDescending(t => t.TransNo)
                    .ToList();
        }

        [OperationContract]
        public Result DoUtmTxns(DateTime dt)
        {
            return (new UtmInterface()).AddTxnListToUtm(dt);
        }
        [OperationContract]
        public List<ProductOrEquipment> ProductOrEquipments(bool is_product)
        {
            if (is_product)
                return db.Products
                    .Where(w => w.Status == true && w.Length == 0)
                    .ToArray()
                    .Select(s => new ProductOrEquipment()
                    {
                        Code = s.ProdCode,
                        Name = s.Name,
                        Price = s.Price,
                        Description = "Хугацаа:" + s.Length + " , Шилжих:" + s.NextProdCode
                    }).ToList();
            else
                return db.Equipments
                    .Where(w => w.Status == true)
                    .Select(s => new ProductOrEquipment()
                    {
                        Code = s.EquipCode,
                        Name = s.Name,
                        Price = s.Price,
                        Description = "Хэмжих нэгж:" + s.Unit
                    }).ToList();

        }

        [OperationContract]
        public decimal ContractBalance(DateTime date, long cont_id)
        {
            return 100;
        }

        [OperationContract]
        public List<vw_Transaction> LastTransactions(long contract_no)
        {
            //Сүүлд хийсэн 10 гүйлгээг илгээх
            return db.vw_Transaction.Where(w => w.ContractNo == contract_no).OrderByDescending(t => t.TxnDate).Take(20).ToList();
        }

        [OperationContract]
        public int NewContractTransactions(long contNo, DateTime? txnDate, decimal? txnAmountEquip, decimal? txnAmount, decimal? txnPaidAmount, int? userNo, int? branchNo, string hostIP, string txnDesc,decimal c1)
        {
            return db.sp_NewContractTransaction(contNo, txnDate, txnDesc, txnAmountEquip, txnAmount, txnPaidAmount, userNo, branchNo, hostIP, c1);
            //return db.Transactions.Where(w => w.ContractNo == contract_no).OrderByDescending(t => t.TxnDate).Take(10).ToList();
        }

        [OperationContract]
        public sp_ContDebit_Result ContractDebit(Nullable<global::System.Int64> contNo, Nullable<global::System.DateTime> calcDate)
        {
            return db.sp_ContDebit(contNo,calcDate).FirstOrDefault();
            //return db.Transactions.Where(w => w.ContractNo == contract_no).OrderByDescending(t => t.TxnDate).Take(10).ToList();
        }

        [OperationContract]
        public Result CalculateDebit(global::System.String calcDate, Nullable<global::System.DateTime> txnDate, Nullable<global::System.Int32> userNo, Nullable<global::System.Int32> branchNo, global::System.String hostIP)
        {
            try
            {
                db.sp_CalculateDebit(calcDate, txnDate, userNo, branchNo, hostIP);
                return new Result() { Code = 0, Message = "Гүйлгээ амжилттай хийгдлээ" };
            }
            catch (Exception ex)
            {
                return new Result(1, "Гүйлгээ хийхэд алдаа:" + ex.Message);
            }
        }
        #endregion
    }
}
